/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.miage.util.ics;

import com.miage.edt.bean.Seance;
import java.io.FileOutputStream;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.fortuna.ical4j.data.CalendarBuilder;
import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.model.*;
import net.fortuna.ical4j.model.component.Daylight;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.component.VTimeZone;
import net.fortuna.ical4j.model.property.*;

/**
   /**
   * Class used for generating ICS calendar of the Miage.
   * <p>
   *
   * @author Legond-Aubry Fabrice
 */
public class GenerateurIcs {

    private Calendar calendar;
    private String myName;
    private TimeZone timezone;
    private VTimeZone tz;

    public TimeZone getTimezone() {
        return timezone;
    }

    public VTimeZone getTz() {
        return tz;
    }

   /**
   * Basic constructor of the class. Create a calendar in the France timezone
   * with daylight saving rules. 
   * <p>
   *
   * @param myName filename of the calendar ics file to begenerated
   */
    public GenerateurIcs(String myName) {
        System.out.println("Instanciation du calendrier '" + myName + "'.");
        calendar = new Calendar();
        calendar.getProperties().add(new ProdId("-//Fabrice_LEGOND-AUBRY_EDTmiage//iCal4j 1.0//EN"));
        calendar.getProperties().add(Version.VERSION_2_0);
        calendar.getProperties().add(CalScale.GREGORIAN);
        this.myName = myName;
        // Create a TimeZone
        TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
        timezone = registry.getTimeZone(ConstantesIcs.timeZoneStr);
        tz = timezone.getVTimeZone();
        // don't forget to add the timezone to the calendar
        calendar.getComponents().add(tz);
    }

   /**
   * This method effectively write the calendar in the file given in the
   * constructor. Before writing, the method perform a call to the validate
   * method. In case of exception in the validation the file will not be
   * written.
   * <p>
   * @return true if the file was written, false otherwise
   *
   */
    public boolean ecritCalendrier() {
        FileOutputStream fout;
        try {
            calendar.validate();
        } catch (ValidationException ve) {
            System.out.println("Calendrier '" + myName + "' vide ou invalide. Pas de sauvegarde.");
            Logger.getLogger(GenerateurIcs.class.getName()).log(Level.SEVERE, null, ve);
            return false;
        }
        try {
            fout = new FileOutputStream(myName);
            System.out.println("Sauvegarde du calendrier '" + myName + "'.");
            CalendarOutputter outputter = new CalendarOutputter();
            outputter.output(calendar, fout);
            return true;
        } catch (Exception ex) {
            System.out.println("Erreur de sauvegarde du calendrier '" + myName+"'.");
            Logger.getLogger(GenerateurIcs.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    /*
     * This method get an object Seance of the EDT application and create
     * an event in the calendar accordingly to the parameters in the object s.
     * <p>
     * 
     * @param s The Seance from which we create an event entry in the calendar
     */
    public VEvent ajouterSeance(Seance s) {
        // Parse the date format string "dd/MM/yyyy HH:mm" to a gregorian
        // calendar object (GregorianCalendar).
        SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm");
        ParsePosition pos = new ParsePosition(0);
        java.util.Date debutJavaUtilDate = formatter.parse(s.getDateSeance() + " " + s.getHeureDeb(), pos);
        GregorianCalendar date_debut = new GregorianCalendar(timezone);
        date_debut.setTime(debutJavaUtilDate);
        GregorianCalendar date_fin = (GregorianCalendar) date_debut.clone();
        // Add the duration of the seance (duration is a float value of hours).
        // 1.5 hours = 1 hour and 30 minutes
        // Create a end date by cloning the start date and adding the duration
        int d = (int) (s.getDuree() * 60);
        date_fin.add(java.util.Calendar.MINUTE, d);
        DateTime _debut = new DateTime(date_debut.getTime());
        DateTime _fin = new DateTime(date_fin.getTime());
        // Create the new event for the calendar
        VEvent cours = new VEvent(_debut, _fin, "Cours " + s.getIntitule());
        cours.getProperties().add(tz.getTimeZoneId());
        // Add attributes
        // Add attribute Uid is an event id
        // Uid has the form Scholar_Year-Seance_Id got from the database
        Uid u = new Uid(s.getAnneeUniv() + "-" + s.getIdSeance());
        cours.getProperties().add(u);
        // Add our own timestamp attribute to avoid auto generated one
        // else it will be considered new event each time we regenerate the
        // calendar and we absolutely do not want it.
        // Timestamp will be the first september of the year of the element
        // AnneUniv of s (AnneUniv has the form Year_Begin-Year_End so we get
        // Yar_Begin).
        int y = Integer.parseInt(s.getAnneeUniv().substring(0, s.getAnneeUniv().indexOf("-")));
        GregorianCalendar dtstamp = new GregorianCalendar(y, 9, 1);
        dtstamp.setTimeZone(timezone);
        cours.getProperties().remove(cours.getDateStamp());
        cours.getProperties().add(new DtStamp(new DateTime(dtstamp.getTime())));
        cours.getProperties().add(new Location(s.getSalleDesignation()));
        cours.getProperties().add(new Description(
                "Intervenant: " + s.getProfesseur() + " " + s.getProfPrenom() +
                ConstantesIcs.newline + "Promo: " + s.getPromotion()));
        // Add constant attributes
        cours.getProperties().add(ConstantesIcs._p_c);
        cours.getProperties().add(ConstantesIcs._p_pc);
        cours.getProperties().add(ConstantesIcs._p_city);
        cours.getProperties().add(ConstantesIcs._p_sa);
        cours.getProperties().add(ConstantesIcs._p_esa);
        cours.getProperties().add(ConstantesIcs._p_url);
        cours.getProperties().add(ConstantesIcs._p_tel);
        calendar.getComponents().add(cours);
        return cours;
    }
}
